package com.cskaoyan.javase.oop3.interface2.introduction1;

/**
 * @description: 接口的引入
 * @author: wuguidong@cskaoyan.onaliyun.com
 **/

/**
 * 做开发：就叫写接口(的实现)
 * > 引例
 * > 回想Animal继承体系的案例，现在我们把Animal设计成抽象类
 * > 产品经理给了新需求
 * - 现在有一部分猫和狗，经过了特殊训练
 *   - 都可以直立行走（Walk Upright）和骑自行车（Ride Bike）
 * - 那么该怎么去描述这群特殊技能的猫狗呢？
 *
 * 这里立刻想到重新定义一个类
 * SuperDog和SuperCat 继承Dog，Cat的基础上然后添加独有方法
 * 思考这样做有什么缺点：
 * 最大的缺点就是代码没有复用，代码有冗余
 * 如果又来一个猴子，猪 也经过训练 变成了超级猪 猪猪侠
 * 代码不能复用，就很烦
 * 改进思路：
 * 可以把这两个方法提取到一个类中，然后让SuperDog和SuperCat继承它
 * 实际上这个思路没毛病，但是做不到
 * 1，Java不支持多继承，没有办法再继承一个类 语法层面上
 * 2，设计层面上来看，大家思考什么是继承，或者说两个类有什么关系才能继承？is-a
 * 骑自行车和是一个超级狗有关系吗？
 * 所以这里用继承的思想，从设计角度来说就是错误的
 *
 * 也就是说，现在已有的知识已经不能够解决我们这个问题了
 * 于是我们需要引入一种：不受多继承限制，不是继承的数据类型
 * 并且它不是is-a关系
 * 这种东西就是接口
 * 接口interface是一种和类class平级关系的数据类型
 * 语法：[访问权限修饰符] interface 接口名{
 * }
 * 接口的命名规范：
 * 接口普遍喜欢用一个I开头，不这么用也没关系
 *
 * 接口中的方法必须是抽象方法（java8之前）
 * 怎么去继承一个接口？
 * 接口的继承称之为实现，使用关键字implements
 * 接口虽然叫做实现，但是接口和实现类仍然是父子类关系
 *
 * 接口的思想：
 * 虽然看起来实现接口后，还是要重写方法，甚至还多了一个注解，更麻烦了
 * 但是接口定义了一种规范，表示只要实现了这个接口，必须能够做一些事情
 * 这在开发中很重要，我们总是先写接口，再写具体代码
 * 接口起到一个约束和规范的作用
 * 起到一个告诉你该咋写的作用
 * 类比生活中的接口，只要我的设备实现了TypeC接口充电功能，那么我随便拿一条TypeC的线都能充电
 *
 * 重点：
 * 继承是is-a关系，但是接口的实现就不是is-a了
 * 它是一种like-a的关系
 * 表示实现接口后，像XX，就是实现功能，是对功能的扩展
 *
 * 接口中没有普通成员变量和普通成员方法
 *
 * 当一个类继承另一个类的同时，又实现接口
 * - 必须要将实现接口放在继承类后面
 *
 * 接口不能实例化 就是不能创建对象
 * 一个类只能够直接继承一个类，这是单继承，接口不受多继承限制，接口可以多实现
 * 单继承的时候，我们说过，Java虽然不支持直接的多继承，但是通过接口可以实现真正意义上的多继承
 *
 */
public class Demo {
    public static void main(String[] args) {
        //'ISpecialSkill' is abstract; cannot be instantiated
        //ISpecialSkill iSpecialSkill = new ISpecialSkill();
    }
}

abstract class Animal {
    public abstract void shout();//'{' or ';' expected
}
class Cat extends Animal {
    @Override
    public void shout() {
        System.out.println("猫叫");
    }
}
class Dog extends Animal {
    @Override
    public void shout() {
        System.out.println("狗叫");
    }
}
class SuperDog  extends Dog implements ISpecialSkill{
    @Override
    public void rideBike() {
        System.out.println("骑自行车");
    }
    @Override
    public void walkUpright() {
        System.out.println("直立行走");
    }
}
class SuperCat extends Cat implements ISpecialSkill,ITest{
    @Override
    public void rideBike() {
        System.out.println("骑自行车");
    }
    @Override
    public void walkUpright() {
        System.out.println("直立行走");
    }
    //public void test(){}

}
//这个接口是为了实现特殊技能
interface ISpecialSkill{
    //Interface abstract methods cannot have body
    public void rideBike();//接口中的方法默认都是抽象的
    public void walkUpright();
}
abstract class Test implements ISpecialSkill{
    //抽象类中有抽象方法，没毛病
}
interface ITest{}
